{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 张量的构造和使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "构造张量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "t1 = torch.tensor([0., 1., 2.])\n",
    "t2 = torch.tensor([[0., 1., 2.], [3., 4., 5.], [6., 7., 8.]])\n",
    "t3 = torch.tensor([[[0., 1., 2.], [3., 4., 5.], [6., 7., 8.]],\n",
    "        [[9., 10., 11.], [12., 13., 14.], [15., 16., 17.]],\n",
    "        [[18., 19., 20.], [21., 22., 23.], [24., 25., 26.]]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "t1 = torch.empty(2) # 未初始化\n",
    "t2 = torch.zeros(2, 2) # 各元素值.\n",
    "t3 = torch.ones(2, 2, 2) # 各元素值为1.\n",
    "t4 = torch.full((2, 2, 2, 2), 3.) # 各元素值为3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0., 1.],\n",
      "        [2., 3.]])\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "t2 = torch.empty(2, 2)\n",
    "t2[0, 0] = 0.\n",
    "t2[0, 1] = 1.\n",
    "t2[1, 0] = 2.\n",
    "t2[1, 1] = 3.\n",
    "print(t2)\n",
    "print(t2.equal(torch.tensor([[0., 1.], [2., 3.]])))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.zeros(2, 3, 4)\n",
    "torch.ones(2, 3, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 1.],\n",
       "        [1., 1.]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.ones_like(t2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0., 1., 2., 3.])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.linspace(0, 3, steps=4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "张量的性质"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data = tensor([[0., 1.],\n",
      "        [2., 3.]])\n",
      "size = torch.Size([2, 2])\n",
      "dim = 2\n",
      "numel = 4\n"
     ]
    }
   ],
   "source": [
    "print('data = {}'.format(t2))\n",
    "print('size = {}'.format(t2.size()))\n",
    "print('dim = {}'.format(t2.dim()))\n",
    "print('numel = {}'.format(t2.numel()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.float32"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t2.dtype"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "改变张量的大小"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tc = tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])\n",
      "t322 = tensor([[[ 0,  1],\n",
      "         [ 2,  3]],\n",
      "\n",
      "        [[ 4,  5],\n",
      "         [ 6,  7]],\n",
      "\n",
      "        [[ 8,  9],\n",
      "         [10, 11]]])\n",
      "t43 = tensor([[ 0,  1,  2],\n",
      "        [ 3,  4,  5],\n",
      "        [ 6,  7,  8],\n",
      "        [ 9, 10, 11]])\n"
     ]
    }
   ],
   "source": [
    "tc = torch.arange(12) # 张量大小 (12,)\n",
    "print('tc = {}'.format(tc))\n",
    "t322 = tc.reshape(3, 2, 2) # 张量大小 (3, 2, 2)\n",
    "print('t322 = {}'.format(t322))\n",
    "t43 = t322.reshape(4, 3) # 张量大小 (4, 3)\n",
    "print('t43 = {}'.format(t43))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "t21 = tensor([[ 5.],\n",
      "        [-9.]])\n",
      "t21 = tensor([[ 5.],\n",
      "        [-9.]])\n"
     ]
    }
   ],
   "source": [
    "t12 = torch.tensor([[5., -9.],])\n",
    "t21 = t12.transpose(0, 1)\n",
    "print('t21 = {}'.format(t21))\n",
    "t21 = t12.t()\n",
    "print('t21 = {}'.format(t21))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "t12 = tensor([[ 5., -9.]])\n",
      "t34 = tensor([[ 5., -9.,  5., -9.],\n",
      "        [ 5., -9.,  5., -9.],\n",
      "        [ 5., -9.,  5., -9.]])\n"
     ]
    }
   ],
   "source": [
    "t12 = torch.tensor([[5., -9.],])\n",
    "print('t12 = {}'.format(t12))\n",
    "t34 = t12.repeat(3, 2)\n",
    "print('t34 = {}'.format(t34))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "t44 = tensor([[ 0,  1,  2,  3],\n",
      "        [ 4,  5,  6,  7],\n",
      "        [ 8,  9, 10, 11],\n",
      "        [12, 13, 14, 15]])\n",
      "t23 = tensor([[ 4,  5,  6],\n",
      "        [ 8,  9, 10]])\n"
     ]
    }
   ],
   "source": [
    "t44 = torch.arange(16).reshape(4, 4)\n",
    "print('t44 = {}'.format(t44))\n",
    "t23 = t44[1:-1, :3]\n",
    "print('t23 = {}'.format(t23))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "张量的数学运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 8., 10., 12.],\n",
      "        [14., 16., 18.]])\n",
      "tensor([[-6., -6., -6.],\n",
      "        [-6., -6., -6.]])\n",
      "tensor([[ 7., 16., 27.],\n",
      "        [40., 55., 72.]])\n",
      "tensor([[0.1429, 0.2500, 0.3333],\n",
      "        [0.4000, 0.4545, 0.5000]])\n",
      "tensor([[1.0000e+00, 2.5600e+02, 1.9683e+04],\n",
      "        [1.0486e+06, 4.8828e+07, 2.1768e+09]])\n",
      "tensor([[1.0000, 1.0905, 1.1298],\n",
      "        [1.1487, 1.1576, 1.1610]])\n"
     ]
    }
   ],
   "source": [
    "tl = torch.tensor([[1., 2., 3.], [4., 5., 6.]])\n",
    "tr = torch.tensor([[7., 8., 9.], [10., 11., 12.]])\n",
    "print(tl + tr) # 加法\n",
    "print(tl - tr) # 减法\n",
    "print(tl * tr) # 乘法\n",
    "print(tl / tr) # 除法\n",
    "print(tl ** tr) # 有理数次乘方\n",
    "print(tl ** (1 / tr)) # 有理数次开方"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[5., 5., 5., 5.],\n",
      "        [5., 5., 5., 5.],\n",
      "        [5., 5., 5., 5.]])\n",
      "tensor([-6., -6.])\n",
      "tensor([[[2., 2., 2., 2.],\n",
      "         [2., 2., 2., 2.],\n",
      "         [2., 2., 2., 2.]],\n",
      "\n",
      "        [[2., 2., 2., 2.],\n",
      "         [2., 2., 2., 2.],\n",
      "         [2., 2., 2., 2.]]])\n"
     ]
    }
   ],
   "source": [
    "print(torch.zeros(3, 4) + 5) # 得到各元素全为5的大小为(3,4)的张量\n",
    "print(-6 * torch.ones(2)) # 得到各元素全为-6的大小为(2,)的张量\n",
    "print(torch.ones(2, 3, 4) + torch.ones(4)) # 得到各元素全为2的大小为(2,3,4)的张量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sqrt = tensor([[[0.0000, 1.0000, 1.4142, 1.7321],\n",
      "         [2.0000, 2.2361, 2.4495, 2.6458],\n",
      "         [2.8284, 3.0000, 3.1623, 3.3166]],\n",
      "\n",
      "        [[3.4641, 3.6056, 3.7417, 3.8730],\n",
      "         [4.0000, 4.1231, 4.2426, 4.3589],\n",
      "         [4.4721, 4.5826, 4.6904, 4.7958]]])\n",
      "sum = 276.0\n",
      "prod = 0.0\n",
      "norm(2) = 65.75712585449219\n",
      "cumsum = tensor([[[ 0.,  1.,  2.,  3.],\n",
      "         [ 4.,  5.,  6.,  7.],\n",
      "         [ 8.,  9., 10., 11.]],\n",
      "\n",
      "        [[12., 14., 16., 18.],\n",
      "         [20., 22., 24., 26.],\n",
      "         [28., 30., 32., 34.]]])\n",
      "cumprod = tensor([[[0.0000e+00, 1.0000e+00, 2.0000e+00, 3.0000e+00],\n",
      "         [0.0000e+00, 5.0000e+00, 1.2000e+01, 2.1000e+01],\n",
      "         [0.0000e+00, 4.5000e+01, 1.2000e+02, 2.3100e+02]],\n",
      "\n",
      "        [[1.2000e+01, 1.3000e+01, 1.4000e+01, 1.5000e+01],\n",
      "         [1.9200e+02, 2.2100e+02, 2.5200e+02, 2.8500e+02],\n",
      "         [3.8400e+03, 4.6410e+03, 5.5440e+03, 6.5550e+03]]])\n"
     ]
    }
   ],
   "source": [
    "t234 = torch.arange(24, dtype=torch.float).reshape(2, 3, 4)\n",
    "print('sqrt = {}'.format(t234.sqrt()))\n",
    "print('sum = {}'.format(t234.sum()))\n",
    "print('prod = {}'.format(t234.prod()))\n",
    "print('norm(2) = {}'.format(t234.norm(2)))\n",
    "print('cumsum = {}'.format(t234.cumsum(dim=0)))\n",
    "print('cumprod = {}'.format(t234.cumprod(dim=1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pow = tensor([1, 2, 9])\n",
      "exp = tensor([1.1052, 0.9900])\n",
      "sin = tensor([[0.7068]])\n"
     ]
    }
   ],
   "source": [
    "tp = torch.pow(torch.arange(1, 4), torch.arange(3))\n",
    "print('pow = {}'.format(tp))\n",
    "te = torch.exp(torch.tensor([0.1, -0.01]))\n",
    "print('exp = {}'.format(te))\n",
    "ts = torch.sin(torch.tensor([[3.14 / 4,],]))\n",
    "print('sin = {}'.format(ts))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "frac = tensor([0.0000, 0.3000, 0.6000, 0.9000, 0.2000])\n",
      "clamp = tensor([0.5000, 1.0000, 2.0000, 3.0000, 3.5000])\n"
     ]
    }
   ],
   "source": [
    "t5 = torch.arange(5, dtype=torch.float)\n",
    "tf = torch.frac(t5 * 0.3)\n",
    "print('frac = {}'.format(tf))\n",
    "tc = torch.clamp(t5, 0.5, 3.5)\n",
    "print('clamp = {}'.format(tc))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "张量的拼接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tc0 = tensor([[  0.,   1.,   2.,   3.],\n",
      "        [  4.,   5.,   6.,   7.],\n",
      "        [  8.,   9.,  10.,  11.],\n",
      "        [ -0.,  -1.,  -2.,  -3.],\n",
      "        [ -4.,  -5.,  -6.,  -7.],\n",
      "        [ -8.,  -9., -10., -11.]])\n",
      "tc1 = tensor([[  0.,   1.,   2.,   3.,   0.,   1.,   2.,   3.,  -0.,  -1.,  -2.,  -3.,\n",
      "          -0.,  -1.,  -2.,  -3.],\n",
      "        [  4.,   5.,   6.,   7.,   4.,   5.,   6.,   7.,  -4.,  -5.,  -6.,  -7.,\n",
      "          -4.,  -5.,  -6.,  -7.],\n",
      "        [  8.,   9.,  10.,  11.,   8.,   9.,  10.,  11.,  -8.,  -9., -10., -11.,\n",
      "          -8.,  -9., -10., -11.]])\n"
     ]
    }
   ],
   "source": [
    "tp = torch.arange(12, dtype=torch.float).reshape(3, 4)\n",
    "tn = -tp\n",
    "tc0 = torch.cat([tp, tn], 0)\n",
    "print('tc0 = {}'.format(tc0))\n",
    "tc1 = torch.cat([tp, tp, tn, tn], 1)\n",
    "print('tc1 = {}'.format(tc1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ts0 = tensor([[[  0.,   1.,   2.,   3.],\n",
      "         [  4.,   5.,   6.,   7.],\n",
      "         [  8.,   9.,  10.,  11.]],\n",
      "\n",
      "        [[ -0.,  -1.,  -2.,  -3.],\n",
      "         [ -4.,  -5.,  -6.,  -7.],\n",
      "         [ -8.,  -9., -10., -11.]]])\n",
      "ts1 = tensor([[[  0.,   1.,   2.,   3.],\n",
      "         [  0.,   1.,   2.,   3.],\n",
      "         [ -0.,  -1.,  -2.,  -3.],\n",
      "         [ -0.,  -1.,  -2.,  -3.]],\n",
      "\n",
      "        [[  4.,   5.,   6.,   7.],\n",
      "         [  4.,   5.,   6.,   7.],\n",
      "         [ -4.,  -5.,  -6.,  -7.],\n",
      "         [ -4.,  -5.,  -6.,  -7.]],\n",
      "\n",
      "        [[  8.,   9.,  10.,  11.],\n",
      "         [  8.,   9.,  10.,  11.],\n",
      "         [ -8.,  -9., -10., -11.],\n",
      "         [ -8.,  -9., -10., -11.]]])\n"
     ]
    }
   ],
   "source": [
    "tp = torch.arange(12, dtype=torch.float).reshape(3, 4)\n",
    "tn = -tp\n",
    "ts0 = torch.stack([tp, tn], 0)\n",
    "print('ts0 = {}'.format(ts0))\n",
    "ts1 = torch.stack([tp, tp, tn, tn], 1)\n",
    "print('ts1 = {}'.format(ts1))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
